//
// Created by lxinp on 2022/8/30.
//

#include "ht_iterator.h"


template<typename K, typename V>
HashTable<K, V>::iterator::iterator() : impl(nullptr) {}


template<typename K, typename V>
HashTable<K, V>::iterator::iterator(const iterator& other) {
    copy(other);
}


template<typename K, typename V>
HashTable<K, V>::iterator::iterator(HTIteratorImpl* nimpl) : impl(nimpl) {}


template<typename K, typename V>
const typename HashTable<K, V>::iterator& HashTable<K, V>::iterator::operator=(const iterator& rhs) {
    if (this != &rhs) {
        clear();
        copy(rhs);
    }
    return *this;
}


template<typename K, typename V>
HashTable<K, V>::iterator::~iterator() { clear(); }


template<typename K, typename V>
void HashTable<K, V>::iterator::copy(const iterator& other) {
    if (other.impl == nullptr) impl = nullptr;
    else impl = other.impl->clone();
}


template<typename K, typename V>
void HashTable<K, V>::iterator::clear() {
    delete impl;
    impl = nullptr;
}


template<typename K, typename V>
typename HashTable<K, V>::iterator& HashTable<K, V>::iterator::operator++() {
    ++(*impl);
    return *this;
}


template<typename K, typename V>
typename HashTable<K, V>::iterator HashTable<K, V>::iterator::operator++(int) {
    iterator temp(*this);
    ++(*impl);
    return temp;
}


template<typename K, typename V>
bool HashTable<K, V>::iterator::operator==(const HashTable<K, V>::iterator& rhs) const {
    if (!impl) return rhs.impl == nullptr;
    if (!rhs.impl) return impl == nullptr;
    return *impl == *(rhs.impl);
}


template<typename K, typename V>
bool HashTable<K, V>::iterator::operator!=(const HashTable<K, V>::iterator& rhs) const {
    return *this != rhs;
}


template<typename K, typename V>
const std::pair<K, V> &HashTable<K, V>::iterator::operator*() {
    return *(*impl);
}


template<typename K, typename V>
const std::pair<K, V>* HashTable<K, V>::iterator::operator->() {
    return &(*(*impl));
}
